/*
 * @Date: 2023-03-21 16:34:16
 * @LastEditors: Zireael 1193875164@qq.com
 * @LastEditTime: 2023-03-21 21:44:53
 * @FilePath: \A19\backend\src\shared\EncryptUtil.ts
 */
import CryptoJS from "crypto-js";
import util from 'util';

const CryptoJSEx = {
  ...CryptoJS,
  enc: {
    ...CryptoJS.enc,
    u8array: {
      stringify: function (wordArray:CryptoJS.lib.WordArray) {
        // Shortcuts
        const words = wordArray.words;
        const sigBytes = wordArray.sigBytes;
        // Convert
        const u8 = new Uint8Array(sigBytes);
        for (let i = 0; i < sigBytes; i++) {
          const byte = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
          u8[i] = byte;
        }
        return u8;
      },
      parse: function (u8arr: Uint8Array) {
        // Shortcut
        const len = u8arr.length;
        // Convert
        const words:number[] = [];
        for (let i = 0; i < len; i++) {
          words[i >>> 2] |= (u8arr[i] & 0xff) << (24 - (i % 4) * 8);
        }
        return CryptoJS.lib.WordArray.create(words, len);
      },
    },
  },
};

const secret = "妄想☆ふぇてぃっしゅ!";
const iv = "zireael"
//@ts-ignore
const encoderCons = util.TextEncoder?util.TextEncoder:TextEncoder
const encoder = new encoderCons()

const keyBv = new Uint8Array(encoder.encode(secret));
const ivBv = new Uint8Array(encoder.encode(iv));

const keyWA = CryptoJSEx.enc.u8array.parse(keyBv);
const ivWA = CryptoJSEx.enc.u8array.parse(ivBv);

export class EncryptUtil {
  // 加密
  static encrypt(buf: Uint8Array): Uint8Array {
    const acontent = buf;
    const contentWA = CryptoJSEx.enc.u8array.parse(acontent);
    // const dcBase64String = contentWA.toString(CryptoJSEx.enc.Base64);
    const encrypted = CryptoJSEx.AES.encrypt(contentWA, keyWA, {
      iv: ivWA,
      mode: CryptoJSEx.mode.CFB,
      padding: CryptoJSEx.pad.NoPadding,
    });
    const bv = CryptoJSEx.enc.u8array.stringify(encrypted.ciphertext);

    return bv;
  }

  // 解密
  static decrypt(buf: Uint8Array): Uint8Array {
    const acontent = buf;
    const contentWA = CryptoJSEx.enc.u8array.parse(acontent);
    const dcBase64String = contentWA.toString(CryptoJSEx.enc.Base64);
    const decrypted = CryptoJSEx.AES.decrypt(dcBase64String, keyWA, {
      iv: ivWA,
      mode: CryptoJSEx.mode.CFB,
      padding: CryptoJSEx.pad.NoPadding,
    });
    const bv = CryptoJSEx.enc.u8array.stringify(decrypted);

    return bv;
  }
}
